﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Web;

namespace SocialFront.extensions
{
    public class ImageScale : IHttpHandler
    {
        /// <summary>
        /// Rezise images to the correct output size
        /// TODO: Add PNG and GIF support.
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            int width = 0;
            int height = 0;
            string path;
            if (context.Request["width"] != null)
                width = Int32.Parse(context.Request["width"]);
            else
            {
                width = 30;
            }
            if (context.Request["height"] != null)
                height = Int32.Parse(context.Request["height"]);
            else
            {
                height = 30;
            }

            // get path for 'no thumbnail' image if you want one
            const String noThumbFile = "nothumb.jpg";
            String sNoThumbPath = context.Request.MapPath(
                context.Request.ApplicationPath.TrimEnd('/') + "/images/" + noThumbFile);
            // map requested path
            if (context.Request["ImgFile"] != null)
                path = context.Request.MapPath(context.Request["ImgFile"]);
            else path = sNoThumbPath;


            string directoryToCache = path.Remove(path.LastIndexOf('\\'), path.Length - path.LastIndexOf('\\'));

            string fileName = System.IO.Path.GetFileNameWithoutExtension(path);

            string fileExtension = System.IO.Path.GetExtension(path);

            if ((fileExtension.ToLower() == ".jpg" || fileExtension.ToLower() == ".gif" || fileExtension.ToLower() == ".png") && System.IO.File.Exists(path))
            {
                Bitmap thumbBitmap = new Bitmap(path);
                if (thumbBitmap == null)
                {
                    thumbBitmap = new Bitmap(sNoThumbPath);
                }

                if (context.Request["constrain"] == "1")
                {
                    if (thumbBitmap.Width / width > thumbBitmap.Height / height)
                    {
                        height = (thumbBitmap.Height / (thumbBitmap.Width / width));
                    }
                    else
                    {
                        width = (thumbBitmap.Width / (thumbBitmap.Height / height));
                    }
                }

                fileName = fileName + "_" + width + "x" + height + fileExtension;

                // Get Image from path
                Image image = Image.FromFile(path);
                // Create new small bitmap thumbnail
                Bitmap bmp = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(bmp);
                // Set the antialiasing on the image
                g.SmoothingMode = SmoothingMode.HighQuality;
                // Set the algorythem the image will be created with
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                // Defines the quality of the pixel rendering
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                // Create the rectangle size for the new image
                Rectangle rectDestination = new Rectangle(0, 0, width, height);
                // Draw the new dimensions to the image
                g.DrawImage(image, rectDestination, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);

                if (!File.Exists(directoryToCache + "\\" + fileName))
                {
                    if (context.Request["thumb"] != null && context.Request["thumb"] == "no")
                    {
                        SaveAndRender(context, fileExtension, bmp, fileName, directoryToCache, true);
                    }
                    else
                    {
                        thumbBitmap = (Bitmap)thumbBitmap.GetThumbnailImage(width, height, ThumbCallback, IntPtr.Zero);
                        SaveAndRender(context, fileExtension, bmp, fileName, directoryToCache, true);
                    }
                }
                else
                {
                    thumbBitmap = new Bitmap(directoryToCache + "/" + fileName);
                    SaveAndRender(context, fileExtension, bmp, fileName, directoryToCache, false);
                }

                g.Dispose();
                bmp.Dispose();
            }
            else
            {
                var img = new Bitmap(width, height);
                var g = Graphics.FromImage(img);
                g.Clear(Color.Azure);

                g.FillRectangle(
                    new LinearGradientBrush(new Point(0, 0), new Point(width, height), Color.White,
                                            Color.Blue), 0, 0, width, height);

                g.DrawString("Doh! Lost image!", new Font("verdana", 10, FontStyle.Regular),
                             SystemBrushes.WindowText, new PointF(2, 2));

                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                SaveAndRender(context, fileExtension, img, fileName, directoryToCache, false);
            }
        }

        /// <summary>
        /// Saves the and render.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="fileExtension">The file extension.</param>
        /// <param name="thumbBitmap">The thumb bitmap.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="directoryToCache">The location on disk the file will be saved to.</param>
        /// <param name="isFileToBeSaved">if set to <c>true</c> [the file will be saved to disk].</param>
        private void SaveAndRender(HttpContext context, string fileExtension, Image thumbBitmap, string fileName, string directoryToCache, bool isFileToBeSaved)
        {
            context.Response.Clear();

            switch (fileExtension.ToLower())
            {
                case ".jpg":
                    if (isFileToBeSaved)
                        thumbBitmap.Save(directoryToCache + "\\" + fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    context.Response.ContentType = "image/Jpeg";
                    thumbBitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    break;
                case ".png":
                    if (isFileToBeSaved)
                        thumbBitmap.Save(directoryToCache + "\\" + fileName, System.Drawing.Imaging.ImageFormat.Png);
                    context.Response.ContentType = "image/png";
                    using (MemoryStream stream = new MemoryStream())
                    {
                        thumbBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        stream.WriteTo(context.Response.OutputStream);
                    }
                    break;
                case ".gif":
                    if (isFileToBeSaved)
                        thumbBitmap.Save(directoryToCache + "\\" + fileName, System.Drawing.Imaging.ImageFormat.Gif);
                    context.Response.ContentType = "image/gif";
                    thumbBitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
                    break;
            }
            thumbBitmap.Dispose();
        }

        public bool ThumbCallback() { return false; }

        public bool IsReusable
        {
            get { return true; }
        }
    }
}